package com.wt.springsamples.aop;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;


@Aspect
public class UserLogAspect implements InitializingBean{

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("UserLogAspect InitializingBean 接口的 afterPropertiesSet()方法");
    }

    @Pointcut("execution(public int com.wt.springsamples.aop.AopService.*(..))")
    public void  pointcut(){}

    @Before("pointcut()")
    public void  before(){
        System.out.println("---------before()----------");
    }

    @After("pointcut()")
    public void  after(){
        System.out.println("---------after()----------");
    }

    @AfterReturning(value = "pointcut()",returning = "result")
    public void  afterReturning(JoinPoint joinPoint,Object result){
        System.out.println("目标方法："+joinPoint.getSignature()+" AfterReturning 返回值: "+result);
    }

    @AfterThrowing(value = "pointcut()",throwing = "exception")
    public void  afterThrowing(JoinPoint joinPoint, Exception exception){
        System.out.println("目标方法："+joinPoint.getSignature() +"异常信息："+exception);
    }

    //该形式不能正常运行
//    @Around(value = "pointcut()")
//    public void  around(){
//        System.out.println("目标方法----around----");
//    }

    /**
     * 环绕通知：
     * 注意:Spring AOP的环绕通知会影响到AfterThrowing通知的运行,不要同时使用
     * 环绕通知非常强大，可以决定目标方法是否执行，什么时候执行，执行时是否需要替换方法参数，执行完毕是否需要替换返回值。
     * 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
     */
    @Around(value = "pointcut()")
    public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println("目标方法----around----");
        Object obj = null;
        try {
            obj = proceedingJoinPoint.proceed(); //可以加参数
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return obj;
    }
}
